﻿using System.Security.Cryptography;

namespace Simple.Common.Helpers;

/// <summary>
/// 散列算法帮助类，包含 MD5、SHA1、SHA256 等
/// </summary>
public static class HashHelper
{

    public static string Md5(string context)
    {
        using MD5 md5 = MD5.Create();
        var sb = new StringBuilder();
        byte[] bs = md5.ComputeHash(Encoding.UTF8.GetBytes(context));
        foreach (var b in bs)
            sb.Append($"{b:x2}");
        return sb.ToString();
    }
    private static byte[] GetKey(string key)
    {
        using SHA256 sha256 = SHA256.Create();
        return sha256.ComputeHash(Encoding.UTF8.GetBytes(key));
    }
    public static string GenerateMd5WithTimeAndId(string id, DateTime? time)
    {
        string timestamp = (time ?? DateTime.UtcNow).ToString("yyyyMMddHHmmss");
        string input = timestamp + id;
        string key = "gmh";
        Console.WriteLine(Encrypt(input, key));
        return Encrypt(input, key);
    }
    public static (string id, DateTime time) DecryptAndExtractIdAndTime(string encryptedInput, string key)
    {
        string decryptedInput = Decrypt(encryptedInput, key);

        // 根据输入的格式来解析 id 和 time
        string timestampPart = decryptedInput.Substring(0, 14); // 时间戳的长度为 14
        string idPart = decryptedInput.Substring(14); // 剩下的部分是 id

        DateTime time = DateTime.ParseExact(timestampPart, "yyyyMMddHHmmss", null);
        return (idPart, time);
    }

    public static string Encrypt(string plainText, string key)
    {
        byte[] keyBytes = GetKey(key);

        using Aes aesAlg = Aes.Create();
        aesAlg.Key = keyBytes;
        aesAlg.IV = new byte[16]; // 使用默认 IV，实际应用中应生成随机 IV

        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

        using MemoryStream msEncrypt = new MemoryStream();
        using CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);
        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
        {
            swEncrypt.Write(plainText);
        }

        byte[] encryptedBytes = msEncrypt.ToArray();
        return Convert.ToBase64String(encryptedBytes).Replace('+', '-')
                                .Replace('/', '_');
    }
    public static string Decrypt(string cipherText, string key)
    {
        byte[] keyBytes = GetKey(key);

        using Aes aesAlg = Aes.Create();
        aesAlg.Key = keyBytes;
        aesAlg.IV = new byte[16]; // 使用默认 IV，实际应用中应生成随机 IV

        ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);

        byte[] cipherBytes = Convert.FromBase64String(cipherText.Replace('-', '+').Replace('_', '/'));

        using MemoryStream msDecrypt = new MemoryStream(cipherBytes);
        using CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);
        using StreamReader srDecrypt = new StreamReader(csDecrypt);

        return srDecrypt.ReadToEnd();
    }

    public static string Sha1(string input, string format = "x2")
    {
        var hash = SHA1.Create();
        var hashBytes = hash.ComputeHash(Encoding.UTF8.GetBytes(input));
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < hashBytes.Length; i++)
        {
            sb.Append(hashBytes[i].ToString(format));
        }
        return sb.ToString();
    }

    public static string Sha256(string input, string format = "x2")
    {
        var hash = SHA256.Create();
        var hashBytes = hash.ComputeHash(Encoding.UTF8.GetBytes(input));
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < hashBytes.Length; i++)
        {
            sb.Append(hashBytes[i].ToString(format));
        }
        return sb.ToString();
    }
}
